package com.info.zhiduoduo.pay.sdk.transferpay.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.info.zhiduoduo.common.configs.TransferPayConfig;
import com.info.zhiduoduo.common.exception.SmartException;
import com.info.zhiduoduo.common.utils.DateUtil;
import com.info.zhiduoduo.common.utils.MapUtil;
import com.info.zhiduoduo.pay.sdk.transferpay.model.request.AgentPayReqDTO;
import com.info.zhiduoduo.pay.sdk.transferpay.model.request.BaseReqDTO;
import com.info.zhiduoduo.pay.sdk.transferpay.model.request.QueryAgentPayReqDTO;
import com.info.zhiduoduo.pay.sdk.transferpay.model.request.QueryBalanceReqDTO;
import com.info.zhiduoduo.pay.sdk.transferpay.model.response.AgentPayResDTO;
import com.info.zhiduoduo.pay.sdk.transferpay.model.response.BaseResDTO;
import com.info.zhiduoduo.pay.sdk.transferpay.model.response.QueryAgentPayResDTO;
import com.info.zhiduoduo.pay.sdk.transferpay.model.response.QueryBalanceResDTO;
import com.info.zhiduoduo.pay.sdk.transferpay.util.HttpClient;
import com.info.zhiduoduo.pay.sdk.transferpay.util.ParamUtil;
import com.info.zhiduoduo.pay.sdk.transferpay.util.RSAUtils;
import com.info.zhiduoduo.repository.entity.pay.PaymentMerchant;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;

import static com.info.zhiduoduo.common.constants.StatusMsg.StatusMsg_462;

@Slf4j
@Service
public class TransferPayApiService {

	@Autowired
	TransferPayConfig transferPayConfig;

	public BaseResDTO<QueryBalanceResDTO> queryBalance(QueryBalanceReqDTO reqDTO, PaymentMerchant paymentMerchant) {
		try {
			handleBaseReqDTOParam(reqDTO, transferPayConfig.getQueryBalanceService());
			Map<String, Object> map = MapUtil.obj2ObjMap(reqDTO);
			String result = doCallApi(map, paymentMerchant);
			return JSON.parseObject(result, new TypeReference<BaseResDTO<QueryBalanceResDTO>>() {
			});
		} catch (Exception e) {
			log.error("调用传化查询账户余额报错", e);
			throw SmartException.of(StatusMsg_462);
		}
	}

	public BaseResDTO<AgentPayResDTO> agentPay(AgentPayReqDTO reqDTO, PaymentMerchant paymentMerchant) {
		try {
			handleBaseReqDTOParam(reqDTO, transferPayConfig.getAgentPayService());
			Map<String, Object> map = MapUtil.obj2ObjMap(reqDTO);
			String result = doCallApi(map, paymentMerchant);
			return JSON.parseObject(result, new TypeReference<BaseResDTO<AgentPayResDTO>>() {
			});
		} catch (Exception e) {
			log.error("调用传化支付报错", e);
			throw SmartException.of(StatusMsg_462);
		}
	}

	public BaseResDTO<QueryAgentPayResDTO> queryAgentPay(QueryAgentPayReqDTO reqDTO, PaymentMerchant paymentMerchant) {
		try {
			handleBaseReqDTOParam(reqDTO, transferPayConfig.getQueryAgentPayService());
			Map<String, Object> map = MapUtil.obj2ObjMap(reqDTO);
			String result = doCallApi(map, paymentMerchant);
			return JSON.parseObject(result, new TypeReference<BaseResDTO<QueryAgentPayResDTO>>() {
			});
		} catch (Exception e) {
			log.error("调用传化查询支付结果报错", e);
			throw SmartException.of(StatusMsg_462);
		}
	}

	private String doCallApi(Map<String, Object> map, PaymentMerchant paymentMerchant) {
		String originalMessage = ParamUtil.sortMapByKey(map);
		log.info("传化-->需要签名的数据:{}", originalMessage);
		byte[] signMessage = RSAUtils.signMessage(paymentMerchant.getCaFile(), paymentMerchant.getCaPassword(),
				originalMessage.getBytes());
		String signStr = new String(signMessage);
		map.put("tf_sign", signStr);
		log.info("传化-->接口调用参数:{}", JSON.toJSONString(map));
		String result = HttpClient.sendHttpPost(transferPayConfig.getApiUrl(), map);
		log.info("传化-->接口返回结果:{}", result);
		return result;
	}

	private void handleBaseReqDTOParam(BaseReqDTO reqDTO, String serviceId) {
		reqDTO.setService_id(serviceId)
				.setSign_type("RSA")
				.setTf_timestamp(DateUtil.getString(new Date(), DateUtil.FORMAT_STYLE_7));
	}

}
